/**
 * <pre>
 * Title: 		PortFactoryImpl.java
 * Author:		linriqing
 * Create:	 	2010-7-15 上午11:21:46
 * Copyright: 	Copyright (c) 2010
 * Company:		Shenzhen Helper
 * <pre>
 */
package com.hengpeng.itfin.port.impl;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;
import com.hengpeng.common.configuration.ConfigProvider;
import com.hengpeng.common.configuration.ConfigProviderFactory;
import com.hengpeng.common.constant.Constant;
import com.hengpeng.common.persist.QueryParameter;
import com.hengpeng.common.persist.QueryResult;
import com.hengpeng.common.persist.entity.AbstractEntity;
import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.util.MessageLoger;
import com.hengpeng.itfin.port.PortActiveFactory;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.TransMessage;

/**
 * <pre>
 * 远程接口工厂实现
 * </pre>
 * @author linriqing
 * @version 1.0, 2012-5-21
 */
@Component("portFactoryActiveImpl")
@Lazy
public class PortFactoryActiveImpl implements PortActiveFactory, ApplicationContextAware
{
	private final static Log logger = LogFactory.getLog(PortFactoryActiveImpl.class);

	private static HttpHeaders httpHeaders = null;

	private final static ConfigProvider<String> cp = ConfigProviderFactory
			.getInstance(Constant.HP_COMMON_PROPERTIES_FILEPATH);

	public static HttpHeaders createBasicAuthHeaders(String userName, String password)
	{
		if (httpHeaders == null)
		{
			httpHeaders = new HttpHeaders();
			// Authorization
			String userPassword = userName + ":" + password;
			String encoding = new String(org.apache.commons.codec.binary.Base64.encodeBase64(userPassword.getBytes()),
					Charset.forName("UTF-8"));
			httpHeaders.set("Authorization", "Basic " + encoding);

			// Accept
			List<MediaType> mediaTypes = new ArrayList<MediaType>();
			mediaTypes.add(MediaType.APPLICATION_XML);
			mediaTypes.add(MediaType.APPLICATION_JSON);
			httpHeaders.setAccept(mediaTypes);

			httpHeaders.set("Accept-Charset", "UTF-8");
		}
		return httpHeaders;
	}

	String DigestAuth_ClientId = "clientbasic";

	String DigestAuth_ClientPwd = "clientbasic4happycp";

	String DigestAuth_Key = "acegi";

	String DigestAuth_RealName = "Contacts Realm via Digest Authentication";

	private RestTemplate restTemplate;

	public <T> T doPostTrans(String transName, Class<T> returnType, Object parameter, Object... pathValue)
	{
		String url = cp.getConfigByPrimaryKey("active.service.url") + "/RemoteService/" + transName;
		HttpEntity<Object> entity = new HttpEntity<Object>(parameter, createBasicAuthHeaders(DigestAuth_ClientId,
				DigestAuth_ClientPwd));
		return (T) restTemplate.postForEntity(url, entity, returnType, pathValue).getBody();
	}

	@Override
	public <T extends AbstractEntity> QueryResult<T> remoteQuery(DynamicQuery query, Class<T> clz)
	{
		QueryParameter<T> qp = new QueryParameter<T>();
		qp.setCustomQuery(query);
		qp.setType(clz);
		return this.remoteQuery(qp);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends AbstractEntity> QueryResult<T> remoteQuery(QueryParameter<T> queryParameters)
	{
		QueryResult<T> doPostTrans = this.doPostTrans("remoteQuery", QueryResult.class, queryParameters);
		if (!doPostTrans.getIsSuccess())
		{
			logger.error("远程查询请求处理错误, Query{" + queryParameters.getCustomQuery().getSqlResult().getSql()
					+ "}, Parameter{" + queryParameters.getCustomQuery().getSqlResult().getParamsList() + "}");
		}
		return doPostTrans;
	}

	@Override
	public ResponseMessage remoteTrans(TransMessage transMessage)
	{
		Gson gson = new Gson();

		logger.info("远程交易请求,【transType=" + transMessage.getTransType() + "】,请求参数:{" + gson.toJson(transMessage) + "}");
		ResponseMessage doPostTrans = this.doPostTrans("remoteTrans", ResponseMessage.class, transMessage);
		logger.info("远程交易请求,【transType=" + transMessage.getTransType() + "】,响应信息:{" + gson.toJson(doPostTrans) + "}");
		MessageLoger.print(this.getClass(),
				"远程交易请求{" + gson.toJson(transMessage) + "},响应信息{" + gson.toJson(doPostTrans) + "}");
		return doPostTrans;
	}

	public <T extends ResponseMessage> T remoteTrans(TransMessage transMessage, Class<T> clz)
	{
		return clz.cast(remoteTrans(transMessage));
	}

	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException
	{
		restTemplate = context.getBean(RestTemplate.class);
		DigestAuth_ClientId = cp.getConfigByPrimaryKey("DigestAuth_ClientId");
		DigestAuth_ClientPwd = cp.getConfigByPrimaryKey("DigestAuth_ClientPwd");
		DigestAuth_Key = cp.getConfigByPrimaryKey("DigestAuth_Key");
		DigestAuth_RealName = cp.getConfigByPrimaryKey("DigestAuth_RealName");
	}
}
